// AiFileDetails.cpp : Implementation of CAiFileDetails

#include "stdafx.h"
#include "AiFileDetails.h"


// CAiFileDetails
const static DWORD g_ColumnFlags = SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT | SHCOLSTATE_SLOW;

// {148C00B0-4E6F-4045-B01A-573E18A44D52}
static const GUID guid_AiExtFolderSizeId =  { 0x148c00b0, 0x4e6f, 0x4045, { 0xb0, 0x1a, 0x57, 0x3e, 0x18, 0xa4, 0x4d, 0x52 } };

// {374BD042-1336-474c-9D94-BE09A673F4E0}
static const GUID guid_AiExtFolderMemoId =  { 0x374bd042, 0x1336, 0x474c, { 0x9d, 0x94, 0xbe, 0x9, 0xa6, 0x73, 0xf4, 0xe0 } };


HRESULT CAiFileDetails::Initialize(LPCSHCOLUMNINIT psci)
{
    if(psci != NULL)
    {
        m_strInitFolder = psci->wszFolder;
    }
    else
    {
        m_strInitFolder = _T("");
    }
    return S_OK;
}

HRESULT CAiFileDetails::GetColumnInfo(DWORD dwIndex, __out SHCOLUMNINFO *psci)
{
    if(dwIndex == 0)
    {
        return GetFolderSizeColumnInfo(dwIndex, psci);
    }
    else if(dwIndex == 1)
    {
        return GetFolderMemoColumnInfo(dwIndex, psci);
    }
    else
    {
        return S_FALSE;
    }
}

HRESULT CAiFileDetails::GetItemData(LPCSHCOLUMNID pscid, LPCSHCOLUMNDATA pscd, __out VARIANT *pvarData)
{
    CString strResult;

    if(pscid->fmtid == guid_AiExtFolderSizeId)
    {
        strResult = GetFolderSize(pscd->dwFileAttributes, pscd->wszFile);
    }
    else if(pscid->fmtid == guid_AiExtFolderMemoId)
    {
        strResult = GetFolderMemo(pscd->dwFileAttributes, pscd->wszFile);
    }

    if(strResult.IsEmpty())
    {
        return S_FALSE;
    }
    else
    {
        pvarData->vt = VT_BSTR;
        pvarData->bstrVal = strResult.AllocSysString();
        return S_OK;
    }
}

HRESULT CAiFileDetails::GetFolderSizeColumnInfo(DWORD dwIndex, __out SHCOLUMNINFO *psci)
{
    psci->scid.fmtid    = guid_AiExtFolderSizeId;
    psci->scid.pid      = dwIndex;
    psci->vt            = VT_BSTR;
    psci->fmt           = LVCFMT_RIGHT;
    psci->cChars        = 10;
    psci->csFlags       = g_ColumnFlags;

    CString strTemp;
    strTemp.LoadString(IDS_STRING_FOLDER_SIZE_TITLE);
    lstrcpynW(psci->wszTitle, strTemp, MAX_COLUMN_NAME_LEN);
    strTemp.LoadString(IDS_STRING_FOLDER_SIZE_DESC);
    lstrcpynW(psci->wszDescription, strTemp, MAX_COLUMN_DESC_LEN);

    return S_OK;
}

HRESULT CAiFileDetails::GetFolderMemoColumnInfo(DWORD dwIndex, __out SHCOLUMNINFO *psci)
{
    psci->scid.fmtid    = guid_AiExtFolderMemoId;
    psci->scid.pid      = dwIndex;
    psci->vt            = VT_BSTR;
    psci->fmt           = LVCFMT_RIGHT;
    psci->cChars        = 30;
    psci->csFlags       = g_ColumnFlags;

    CString strTemp;
    strTemp.LoadString(IDS_STRING_FOLDER_MEMO_TITLE);
    lstrcpynW(psci->wszTitle, strTemp, MAX_COLUMN_NAME_LEN);
    strTemp.LoadString(IDS_STRING_FOLDER_MEMO_DESC);
    lstrcpynW(psci->wszDescription, strTemp, MAX_COLUMN_DESC_LEN);

    return S_OK;
}

template <typename T>
int Printf(T num, LPTSTR szBuffer, int uBufferLen)
{
    szBuffer[0] = 0;

    T temp = num;
    int nLen = 0;
    do
    {
        temp /= 10;
        nLen ++;
    }while(temp != 0);

    bool bNeg = (num < 0);

    nLen = nLen / 3 + nLen - (nLen % 3 == 0 ? 1 : 0);

    if((nLen + (bNeg ? 1 : 0)) >= uBufferLen)
    {
        return -1;
    }

    // Negative
    if(bNeg)
    {
        szBuffer[0] = _T('-');
        num = -num;
        szBuffer[nLen + 1] = 0;
    }
    else
    {
        szBuffer[nLen] = 0;
    }

    size_t nLeft = 1;

    temp = num;

    int nBase = bNeg ? 1 : 0;
    nLen += nBase;
    for(nLen--;nLen>=nBase; nLen--, nLeft++)
    {
        szBuffer[nLen] = (temp % 10) + _T('0');
        temp = (temp - temp % 10) / 10;
        if(nLeft % 3 == 0 && temp != 0)
        {
            szBuffer[nLen-1] = _T(',');
            nLen--;
        }
    }

    return nLen;
}

CString CAiFileDetails::GetFolderSize(DWORD dwFileAttr, LPCTSTR szFolderPath)
{
    CString strResult;

    ULONGLONG ulSize = 0L;

    if((dwFileAttr & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
    {
        ulSize = CFSHelper::GetFSHelper().GetFolderSize(szFolderPath);
    }
    else
    {
        ulSize = CFSHelper::GetFSHelper().GetFileSize(szFolderPath);
    }

    if(ulSize > 1024)
    {
        ulSize = ulSize / 1024;
        strResult.Format(_T("%llu KB"), ulSize);
    }
    else
    {
        strResult.Format(_T("%d KB"), (ulSize > 0) ? 1 : 0);
    }
    return strResult;
}

CString CAiFileDetails::GetFolderMemo(DWORD dwFileAttr, LPCTSTR szFolderPath)
{
    CString strResult;

    ULONGLONG ulSize = 0L;

    if((dwFileAttr & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
    {
        ulSize = CFSHelper::GetFSHelper().GetFolderSize(szFolderPath);
    }
    else
    {
        ulSize = CFSHelper::GetFSHelper().GetFileSize(szFolderPath);
    }

    if(ulSize > 1024)
    {
        ulSize = ulSize / 1024;
        TCHAR szBuffer[30];
        Printf(ulSize, szBuffer, 30);
        strResult.Format(_T("%s KB"), szBuffer);
    }
    else
    {
        strResult.Format(_T("%d KB"), (ulSize > 0) ? 1 : 0);
    }
    return strResult;
}